/*
 * FileName: lb-table.vue
 * Remark: element table
 * Project: lb-element-table
 * Author: LiuBing
 * File Created: Tuesday, 19th March 2019 9:55:27 am
 * Last Modified: Tuesday, 19th March 2019 9:55:34 am
 * Modified By: LiuBing
 */

<template>
  <div class="lb-table">
    <el-table
      :show-header="showHeader"
      ref="elTable"
      v-bind="$attrs"
      max-height="450"
      v-on="$listeners"
      :data="data.data"
      :span-method="this.merge ? this.mergeMethod : this.objectSpanMethod"
    >
      <lb-column
        v-bind="$attrs"
        v-for="(item, index) in data.column"
        :key="index"
        :column="item"
        align="center"
        :type="data.type"
      >
      </lb-column>
    </el-table>
    <el-pagination
      class="lb-table-pagination"
      v-if="pagination"
      v-bind="$attrs"
      v-on="$listeners"
      @current-change="paginationCurrentChange"
      :style="{ 'margin-top': paginationTop, 'text-align': paginationAlign }"
    >
    </el-pagination>
  </div>
</template>

<script>
import LbColumn from "./lb-column";
export default {
  props: {
    tableData: {
      type: Object | Array,
      default: () => ({
        column: [],
        type: [],
        data: [],
      }),
    },
    spanMethod: Function,
    pagination: {
      type: Boolean,
      default: false,
    },
    paginationTop: {
      type: String,
      default: "15px",
    },
    paginationAlign: {
      type: String,
      default: "right",
    },
    merge: Array,
    showHeader: {
      type: Boolean,
      default: true,
    },
    reverse: {
      //行列是否转换
      type: Boolean,
      default: () => false,
    },
  },
  components: {
    LbColumn,
  },
  data() {
    return {
      mergeLine: {},
      mergeIndex: {},
      data: {
        column: [],
        type: [],
        data: [],
      },
    };
  },
  created() {
    this.getMergeArr(this.data, this.merge);
    if (this.reverse == true) {
      let obj = new Object();
      obj = JSON.parse(JSON.stringify(this.tableData));
      this.reverseTable(obj.column, obj.data);
      this.$forceUpdate();
    } else {
      this.data = JSON.parse(JSON.stringify(this.tableData));
      this.$forceUpdate();
    }
  },
  computed: {
    dataLength() {
      return this.data.length;
    },
  },
  methods: {
    clearSelection() {
      this.$refs.elTable.clearSelection();
    },
    toggleRowSelection(row, selected) {
      this.$refs.elTable.toggleRowSelection(row, selected);
    },
    toggleAllSelection() {
      this.$refs.elTable.toggleAllSelection();
    },
    toggleRowExpansion(row, expanded) {
      this.$refs.elTable.toggleRowExpansion(row, expanded);
    },
    setCurrentRow(row) {
      this.$refs.elTable.setCurrentRow(row);
    },
    clearSort() {
      this.$refs.elTable.clearSort();
    },
    clearFilter(columnKey) {
      this.$refs.elTable.clearFilter(columnKey);
    },
    doLayout() {
      this.$refs.elTable.doLayout();
    },
    sort(prop, order) {
      this.$refs.elTable.sort(prop, order);
    },
    paginationCurrentChange(val) {
      this.$emit("p-current-change", val);
    },
    getMergeArr(tableData, merge) {
      if (!merge) return;
      this.mergeLine = {};
      this.mergeIndex = {};
      merge.forEach((item, k) => {
        tableData.forEach((data, i) => {
          if (i === 0) {
            this.mergeIndex[item] = this.mergeIndex[item] || [];
            this.mergeIndex[item].push(1);
            this.mergeLine[item] = 0;
          } else {
            if (data[item] === tableData[i - 1][item]) {
              this.mergeIndex[item][this.mergeLine[item]] += 1;
              this.mergeIndex[item].push(0);
            } else {
              this.mergeIndex[item].push(1);
              this.mergeLine[item] = i;
            }
          }
        });
      });
    },
    mergeMethod({ row, column, rowIndex, columnIndex }) {
      const index = this.merge.indexOf(column.property);
      if (index > -1) {
        const _row = this.mergeIndex[this.merge[index]][rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          rowspan: _row,
          colspan: _col,
        };
      }
    },
    // 反转函数
    reverseTable(column, list) {
      try {
        let arr = [];
        for (let i = 0; i < column.length; i++) {
          if (!column[i].children) {
            arr.push(column[i]);
          } else {
            for (let j of column[i].children) {
              j.parents = column[i].label;
              // j.render =column[i].render
            }
            arr.push(...column[i].children);
          }
        }
        const buildData = arr.map((column) => {
          const item = { col0: column.label };
          if (column.parents) {
            item["col"] = column.parents;
          } else {
            item["col"] = " ";
          }
          // console.log(column)
          list.forEach((row, indexs) => {
            item[`col${indexs + 1}`] = row[column.prop];
          });
          return item;
        });
        const buildColumn = [
          {
            prop: "col",
            fixed: "left",
            minWidth: 180,
          },
          {
            prop: "col0",
            fixed: "left",
            minWidth: 180,
          },
        ];
        list.forEach((item, index) => {
          buildColumn.push({
            prop: `col${index + 1}`,
            minWidth: 200,
            render: (h, scope) => {
              return h("div", [
                h("Input", {
                  style: {
                    padding: "8px",
                     width:"95%"
                  },
                   domProps: {
                    value: scope.row[scope.column.property],
                  },
                  on: {
                    "on-change": (event) => {
                      console.log(event);
                      this.data[scope.index][scope.column.property] =
                        event.target.value;
                    },
                  },
                }),
              ]);
            },
          });
        });
        this.data.data = buildData;
        this.data.column = buildColumn;
      } catch (err) {
        console.log(err);
      }
    },
    //合并
    objectSpanMethod({ row, column, rowIndex, columnIndex, visibleData }) {
      try {
        if (this.reverse == true) {
          //当前行号rowIndex、当前列号columnIndex四个属性
          if (row.col.length === 1) {
            if (columnIndex === 1) {
              return {
                rowspan: 1,
                colspan: 2,
              };
            } else if (columnIndex === 0) {
              return {
                rowspan: 0,
                colspan: 0,
              };
            }
          }
          // const fields = ["col"];
          // const cellValue = row[column.property];
          // if (cellValue && fields.includes(column.property)) {
          //   const prevRow = visibleData[rowIndex - 1];
          //   let nextRow = visibleData[rowIndex + 1];
          //   if (prevRow && prevRow[column.property] === cellValue) {
          //     return { rowspan: 0, colspan: 0 };
          //   } else {
          //     let countRowspan = 1;
          //     while (nextRow && nextRow[column.property] === cellValue) {
          //       nextRow = visibleData[++countRowspan + rowIndex];
          //     }
          //     if (countRowspan > 1) {
          //       return { rowspan: countRowspan, colspan: 1 };
          //     }
          //   }
          // }
        }
      } catch (err) {
        console.log(err);
      }
    },
  },
  watch: {
    merge() {
      this.getMergeArr(this.data, this.merge);
    },
    dataLength() {
      this.getMergeArr(this.data, this.merge);
    },
    tableData: {
      //深度监听，可监听到对象、数组的变化
      handler(val, oldVal) {
        if (this.reverse == true) {
          let obj = new Object();
          obj = JSON.parse(JSON.stringify(this.tableData));
          this.reverseTable(obj.column, obj.data);
          this.$forceUpdate();
        } else {
          this.data = JSON.parse(JSON.stringify(this.tableData));
          this.$forceUpdate();
        }
      },
      deep: true, //true 深度监听
    },
  },
};
</script>
